package org.study.dsm.pool.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;

import javax.sql.DataSource;
import java.sql.*;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 作用描述
 *
 * @author doveylovey
 * @version v1.0.0
 * @email 1135782208@qq.com
 * @date 2024年08月08日
 */
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RestController
public class DataSourceController {
    private final @Qualifier("druidDataSource") DataSource druidDataSource;
    private final @Qualifier("hikariDataSource") DataSource hikariDataSource;
    private final @Qualifier("beeDataSource") DataSource beeDataSource;
    private final @Qualifier("dbcp2DataSource") DataSource dbcp2DataSource;

    /**
     * 浏览器访问任意页面时，都会额外再发一个 GET /favicon.ico 请求去找网站图标。
     * 方案1：忽略 favicon.ico，最简单的做法是在 resources/static/ 或 resources/public/ 下放一个 favicon.ico 文件，SpringBoot 会自动返回，不再进入控制器。
     * 方案2：收紧路径匹配：用正则把 {pool} 限制成只能是小写的四个关键字
     * 方案3：spring.mvc.favicon.enabled: false # Boot 2.x 或 spring.web.resources.add-mappings: false # Boot 3.x
     */
    @GetMapping("/{poolName:druid|hikari|bee|dbcp}")
    public Map<String, Object> ping(@PathVariable String poolName) throws Exception {
        Map<String, Object> map = new LinkedHashMap<>() {{
            this.put("poolName", poolName);
            this.put("online", Boolean.FALSE);
        }};
        DataSource dataSource = switch (poolName) {
            case "druid" -> druidDataSource;
            case "hikari" -> hikariDataSource;
            case "bee" -> beeDataSource;
            case "dbcp" -> dbcp2DataSource;
            default -> throw new IllegalArgumentException("未知连接池，名称：" + poolName);
        };
        try (Connection connection = dataSource.getConnection();
             PreparedStatement ps = connection.prepareStatement("SELECT 1");
             ResultSet rs = ps.executeQuery()) {
            if (rs.next()) {
                int testResult = rs.getInt(1);
                map.put("online", Boolean.TRUE);
            }
            String poolClass = dataSource.getClass().getName();
            DatabaseMetaData metaData = connection.getMetaData();

            String username = metaData.getUserName();
            String driverName = metaData.getDriverName();
            String driverVersion = metaData.getDriverVersion();
            int driverMajorVersion = metaData.getDriverMajorVersion();
            int driverMinorVersion = metaData.getDriverMinorVersion();
            int jdbcMajorVersion = metaData.getJDBCMajorVersion();
            int jdbcMinorVersion = metaData.getJDBCMinorVersion();
            int databaseMajorVersion = metaData.getDatabaseMajorVersion();
            int databaseMinorVersion = metaData.getDatabaseMinorVersion();
            String databaseProductName = metaData.getDatabaseProductName();
            String databaseProductVersion = metaData.getDatabaseProductVersion();
            String procedureTerm = metaData.getProcedureTerm();
            String sqlKeywords = metaData.getSQLKeywords();
            String url = metaData.getURL();

            map.put("poolClass", poolClass);
            map.put("username", username);
            map.put("driverName", driverName);
            map.put("driverVersion", driverVersion);
            map.put("url", url);
            return map;
        }
    }
}
